package com.marketing.tenant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.marketing.tenant.entity.TenantConfig;
import com.marketing.tenant.mapper.TenantConfigMapper;
import com.marketing.tenant.service.TenantConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 租户配置服务实现
 */
@Service
public class TenantConfigServiceImpl implements TenantConfigService {

    private static final Logger log = LoggerFactory.getLogger(TenantConfigServiceImpl.class);

    @Autowired
    private TenantConfigMapper tenantConfigMapper;

    @Override
    public List<TenantConfig> getConfigsByTenantId(Long tenantId) {
        try {
            return tenantConfigMapper.selectByTenantId(tenantId);
        } catch (Exception e) {
            log.error("根据租户ID获取配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取租户配置失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getConfigMapByTenantId(Long tenantId) {
        try {
            List<TenantConfig> configs = getConfigsByTenantId(tenantId);
            if (CollectionUtils.isEmpty(configs)) {
                return new HashMap<>();
            }

            return configs.stream()
                    .collect(Collectors.toMap(
                            config -> config.getConfigGroup() + "." + config.getConfigKey(),
                            TenantConfig::getConfigValue,
                            (existing, replacement) -> existing
                    ));
        } catch (Exception e) {
            log.error("根据租户ID获取配置Map失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取租户配置失败: " + e.getMessage());
        }
    }

    @Override
    public List<TenantConfig> getConfigsByGroup(Long tenantId, String configGroup) {
        try {
            return tenantConfigMapper.selectByTenantIdAndGroup(tenantId, configGroup);
        } catch (Exception e) {
            log.error("根据租户ID和配置组获取配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取租户配置失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getConfigMapByGroup(Long tenantId, String configGroup) {
        try {
            List<TenantConfig> configs = getConfigsByGroup(tenantId, configGroup);
            if (CollectionUtils.isEmpty(configs)) {
                return new HashMap<>();
            }

            return configs.stream()
                    .collect(Collectors.toMap(
                            TenantConfig::getConfigKey,
                            TenantConfig::getConfigValue,
                            (existing, replacement) -> existing
                    ));
        } catch (Exception e) {
            log.error("根据租户ID和配置组获取配置Map失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取租户配置失败: " + e.getMessage());
        }
    }

    @Override
    public String getConfigValue(Long tenantId, String configGroup, String configKey) {
        return getConfigValue(tenantId, configGroup, configKey, null);
    }

    @Override
    public String getConfigValue(Long tenantId, String configGroup, String configKey, String defaultValue) {
        try {
            TenantConfig config = tenantConfigMapper.selectByTenantIdAndKey(tenantId, configGroup, configKey);
            return config != null ? config.getConfigValue() : defaultValue;
        } catch (Exception e) {
            log.error("获取单个配置值失败: {}", e.getMessage(), e);
            return defaultValue;
        }
    }

    @Override
    @Transactional
    public boolean saveOrUpdateConfig(TenantConfig config) {
        try {
            if (config.getTenantId() == null || !StringUtils.hasText(config.getConfigGroup()) 
                    || !StringUtils.hasText(config.getConfigKey())) {
                throw new IllegalArgumentException("租户ID、配置组和配置键不能为空");
            }

            // 设置默认值
            if (config.getValueType() == null) {
                config.setValueType("STRING");
            }
            if (config.getIsEncrypted() == null) {
                config.setIsEncrypted(0);
            }
            config.setUpdateTime(LocalDateTime.now());

            // 检查配置是否已存在
            TenantConfig existingConfig = tenantConfigMapper.selectByTenantIdAndKey(
                    config.getTenantId(), config.getConfigGroup(), config.getConfigKey());

            int result;
            if (existingConfig != null) {
                // 更新现有配置
                config.setId(existingConfig.getId());
                config.setCreateTime(existingConfig.getCreateTime());
                if (config.getCreateBy() == null) {
                    config.setCreateBy(existingConfig.getCreateBy());
                }
                result = tenantConfigMapper.updateById(config);
                log.info("更新租户配置成功: 租户ID={}, 配置组={}, 配置键={}", 
                        config.getTenantId(), config.getConfigGroup(), config.getConfigKey());
            } else {
                // 创建新配置
                config.setCreateTime(LocalDateTime.now());
                if (config.getCreateBy() == null) {
                    config.setCreateBy("system");
                }
                result = tenantConfigMapper.insert(config);
                log.info("创建租户配置成功: 租户ID={}, 配置组={}, 配置键={}", 
                        config.getTenantId(), config.getConfigGroup(), config.getConfigKey());
            }

            return result > 0;
        } catch (Exception e) {
            log.error("保存或更新配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("保存配置失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean saveOrUpdateConfigs(List<TenantConfig> configs) {
        try {
            if (CollectionUtils.isEmpty(configs)) {
                return true;
            }

            // 设置默认值和时间戳
            LocalDateTime now = LocalDateTime.now();
            configs.forEach(config -> {
                if (config.getValueType() == null) {
                    config.setValueType("STRING");
                }
                if (config.getIsEncrypted() == null) {
                    config.setIsEncrypted(0);
                }
                config.setUpdateTime(now);
                if (config.getCreateTime() == null) {
                    config.setCreateTime(now);
                }
                if (config.getCreateBy() == null) {
                    config.setCreateBy("system");
                }
            });

            int result = tenantConfigMapper.batchInsertOrUpdate(configs);
            log.info("批量保存租户配置成功: 配置数量={}", configs.size());
            return result > 0;
        } catch (Exception e) {
            log.error("批量保存配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量保存配置失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean deleteConfig(Long tenantId, String configGroup, String configKey) {
        try {
            LambdaQueryWrapper<TenantConfig> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TenantConfig::getTenantId, tenantId)
                    .eq(TenantConfig::getConfigGroup, configGroup)
                    .eq(TenantConfig::getConfigKey, configKey);

            int result = tenantConfigMapper.delete(wrapper);
            log.info("删除租户配置成功: 租户ID={}, 配置组={}, 配置键={}", tenantId, configGroup, configKey);
            return result > 0;
        } catch (Exception e) {
            log.error("删除配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("删除配置失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean deleteConfigsByTenantId(Long tenantId) {
        try {
            int result = tenantConfigMapper.deleteByTenantId(tenantId);
            log.info("删除租户所有配置成功: 租户ID={}, 删除数量={}", tenantId, result);
            return true;
        } catch (Exception e) {
            log.error("删除租户所有配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("删除租户配置失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean initDefaultConfigs(Long tenantId) {
        try {
            // 获取默认配置模板
            List<TenantConfig> defaultConfigs = getDefaultConfigTemplate();
            
            // 为每个配置设置租户ID
            defaultConfigs.forEach(config -> config.setTenantId(tenantId));
            
            // 批量保存默认配置
            return saveOrUpdateConfigs(defaultConfigs);
        } catch (Exception e) {
            log.error("初始化租户默认配置失败: {}", e.getMessage(), e);
            throw new RuntimeException("初始化租户配置失败: " + e.getMessage());
        }
    }

    @Override
    public List<TenantConfig> getDefaultConfigTemplate() {
        List<TenantConfig> defaultConfigs = new ArrayList<>();

        // 系统配置
        TenantConfig themeConfig = new TenantConfig();
        themeConfig.setConfigGroup("SYSTEM");
        themeConfig.setConfigKey("theme");
        themeConfig.setConfigValue("default");
        themeConfig.setValueType("STRING");
        themeConfig.setDescription("系统主题");
        defaultConfigs.add(themeConfig);

        TenantConfig languageConfig = new TenantConfig();
        languageConfig.setConfigGroup("SYSTEM");
        languageConfig.setConfigKey("language");
        languageConfig.setConfigValue("zh-CN");
        languageConfig.setValueType("STRING");
        languageConfig.setDescription("系统语言");
        defaultConfigs.add(languageConfig);

        TenantConfig timezoneConfig = new TenantConfig();
        timezoneConfig.setConfigGroup("SYSTEM");
        timezoneConfig.setConfigKey("timezone");
        timezoneConfig.setConfigValue("Asia/Shanghai");
        timezoneConfig.setValueType("STRING");
        timezoneConfig.setDescription("时区设置");
        defaultConfigs.add(timezoneConfig);

        // 业务配置
        TenantConfig maxUsersConfig = new TenantConfig();
        maxUsersConfig.setConfigGroup("BUSINESS");
        maxUsersConfig.setConfigKey("max_users");
        maxUsersConfig.setConfigValue("100");
        maxUsersConfig.setValueType("NUMBER");
        maxUsersConfig.setDescription("最大用户数");
        defaultConfigs.add(maxUsersConfig);

        TenantConfig storageLimitConfig = new TenantConfig();
        storageLimitConfig.setConfigGroup("BUSINESS");
        storageLimitConfig.setConfigKey("storage_limit");
        storageLimitConfig.setConfigValue("1073741824"); // 1GB
        storageLimitConfig.setValueType("NUMBER");
        storageLimitConfig.setDescription("存储空间限制(字节)");
        defaultConfigs.add(storageLimitConfig);

        // 界面配置
        TenantConfig dashboardLayoutConfig = new TenantConfig();
        dashboardLayoutConfig.setConfigGroup("UI");
        dashboardLayoutConfig.setConfigKey("dashboard_layout");
        dashboardLayoutConfig.setConfigValue("grid");
        dashboardLayoutConfig.setValueType("STRING");
        dashboardLayoutConfig.setDescription("仪表板布局");
        defaultConfigs.add(dashboardLayoutConfig);

        TenantConfig menuStyleConfig = new TenantConfig();
        menuStyleConfig.setConfigGroup("UI");
        menuStyleConfig.setConfigKey("menu_style");
        menuStyleConfig.setConfigValue("vertical");
        menuStyleConfig.setValueType("STRING");
        menuStyleConfig.setDescription("菜单样式");
        defaultConfigs.add(menuStyleConfig);

        return defaultConfigs;
    }
}